/**
 * @file   DocSync.java
 * @author Enrique Madrid <e.madrid@lpcsite.com>
 * @date   Wed Aug 29 07:21:08 2007
 * 
 * @brief  
 * 
 * 
 */

package sim.sync;

import sim.framework.*;
import sim.framework.io.*;
import sim.utils.*;
import sim.utils.*;

import java.util.*;

public final class DocSync extends Document implements FileGets {

    private static final int HIT_TIMESTAMP = 1;

    private static final byte[] FILE_INI_SHEL = FileNames.FILE_SHEL.getBytes();
    private static final byte[] FILE_INI_CONF = FileNames.FILE_APP_CFG.getBytes();
    private static final byte[] FILE_INI_AUTH = FileNames.FILE_AUTH.getBytes();

    private int m_Hit = 0;

    // Marca de tiempo local desde la última sincronización
    private byte[] m_Data = new byte[32];
    private int  m_TimeValue = 0;
    private byte[] m_TimeStamp = null;
    private Vector m_Items = new Vector(64);
    private boolean m_Restart = false;

    public DocSync(Simlet s) {
        super(s);
    }

    public void delete() {
	File.delete(FileNames.FILE_SYNC);
	File.delete(FileNames.LIST_SYNC);
    }

    public boolean load() {
        FileStream file;
        file = (FileStream)FileStream.create(super.m_Simlet,
					     FileNames.FILE_SYNC, 
					     FileStream.MODE_READ);        
        if (file != null) {
            file.gets(this);
            file.close();
        }
	else {
	    setTimeValue(0);
	}

	return true;
    }
    
    public boolean save() {
	FileStream file;
	int len;
	boolean ret = false;
	// Guardar la referencia de sicronización
        file = (FileStream)FileStream.create(super.m_Simlet,
					     FileNames.FILE_SYNC,
					     FileStream.MODE_WRITE);
	if (file != null) {
	    len = Utils.fmtInteger(m_Data, m_TimeValue, 16, 0, Utils.FMT_LEFT);
	    ret = file.puts(m_Data, 0, len);
	    file.close();
	}
	return ret;
    }

    public final boolean fileGetsLine(final byte[] line, int length, int crlf) {
	if (length > crlf) {
	    switch(++m_Hit) {
	    case DocSync.HIT_TIMESTAMP:
		setTimeStamp(line, 0, length - crlf);
	    }
	}
	return true;
    }

    public final int getTimeValue() {
	return m_TimeValue;
    }
    
    public final void setTimeValue(int seconds) {
	int len;
	m_TimeValue = seconds;
	m_TimeStamp = null;
	len = Utils.fmtInteger(m_Data, m_TimeValue, 16, 0, Utils.FMT_LEFT);
	if (len > 0) {
	    m_TimeStamp = new byte[len];
	    Utils.memcpy(m_TimeStamp, 0, m_Data, 0, len);
	}
    }

    public final void setTimeStamp(final byte[] line, int star, int length) {
	m_TimeStamp = new byte[length];
	if (m_TimeStamp != null) {
	    Utils.memcpy(m_TimeStamp, 0, line, 0, length);
	    m_TimeValue = Utils.memtoul(m_TimeStamp, 16); 
	}
    }

    public final byte[] getTimeStamp() {
	return m_TimeStamp;
    }

    public void appendItem(SyncItem item) {
	//#ifdef DEBUG_DOCSYNC
	//# System.out.println("DocSync::appendItem() ENTERED");
	//#endif 
	m_Items.addElement(item);
	//#ifdef DEBUG_DOCSYNC
	//# System.out.println("\titem.m_Name = " + new String(item.m_Name, 0, item.m_Name.length));
	//# System.out.println("\titem.m_Type = " + item.m_Type);
	//# System.out.println("\titem.m_Mode = " + item.m_Mode);
	//#endif
	// Veamos si con este item debemos reiniciar
	if (m_Simlet.isInitOk() && (item.m_Type == SyncItem.TYPE_TXT)) {
	    if (Utils.memcmp(item.m_Name, FILE_INI_SHEL) == 0) {
		m_Restart |= true;
	    }
	    else if (Utils.memcmp(item.m_Name, FILE_INI_CONF) == 0) {
		m_Restart |= true;
	    }
	    else if (Utils.memcmp(item.m_Name, FILE_INI_AUTH) == 0) {
		m_Restart |= true;
	    }
	    //#ifdef DEBUG_DOCSYNC
	    //# if (m_Restart)
	    //# System.out.println("Simlet REINICIARA!!!!");
	    //#endif

	}
	//#ifdef DEBUG_DOCSYNC
	//# System.out.println("DocSync::appendItem() EXITING");
	//#endif 
    }

    public SyncItem removeItem() {
	//#ifdef DEBUG_DOCSYNC
	//# System.out.println("DocSync::removeItem() ENTERED");
	//#endif 
	SyncItem item = null;
	if (m_Items.size() > 0) {
	    item = (SyncItem)m_Items.firstElement();
	    m_Items.removeElement(item);
	    //#ifdef DEBUG_DOCSYNC
	    //# System.out.println("\titem.m_Name = " + new String(item.m_Name, 0, item.m_Name.length));
	    //# System.out.println("\titem.m_Type = " + item.m_Type);
	    //# System.out.println("\titem.m_Mode = " + item.m_Mode);
	    //#endif
	}
	//#ifdef DEBUG_DOCSYNC
	//# System.out.println("DocSync::removeItem() EXITING");
	//#endif 
	return item;
    }

    public boolean restart() {
	return m_Restart;
    }
}
